﻿using System;
using System.Text.RegularExpressions;
using System.Web.Script.Serialization;
using MySql.Data.MySqlClient;
using Splendor_Server.script.logic.player;
using Splendor_Server.script.net;

namespace Splendor_Server.script.db
{
    public class DbManager
    {
        public static MySqlConnection Mysql;
        public static JavaScriptSerializer Js = new JavaScriptSerializer();

        public static bool Connect(string db, string ip, int port, string user, string pw)
        {
            Mysql = new MySqlConnection
            {
                ConnectionString = $"Database={db};Data Source={ip}; port={port};User Id={user}; Password={pw}"
            };

            try
            {
                Mysql.Open();
                Console.WriteLine("[{0}][数据库]Connect successful", NetManager.GetNowTime());

                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]Connect fail, {1}", NetManager.GetNowTime(), ex.Message);
                return false;
            }
        }

        //测试并重连
        private static void CheckAndReconnect()
        {
            try
            {
                if (Mysql.Ping())
                {
                    return;
                }

                Mysql.Close();
                Mysql.Open();
                Console.WriteLine("[{0}][数据库]Reconnect", NetManager.GetNowTime());
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]CheckAndReconnect fail, {1}", NetManager.GetNowTime(), ex.Message);
            }
        }

        //判定安全字符串 防sql注入
        private static bool IsSafeString(string str)
        {
            return !Regex.IsMatch(str, @"[-|;|,|\/|\(|\)|\[|\]|\}|\{|%|@|\*|!|\']");
        }

        //是否存在该用户
        private static bool IsAccountExist(string id)
        {
            CheckAndReconnect();

            if (!DbManager.IsSafeString(id))
            {
                return false;
            }

            string s = string.Format("select * from account where id='{0}';", id);
            //查询
            try
            {
                MySqlCommand cmd = new MySqlCommand(s, Mysql);
                MySqlDataReader dataReader = cmd.ExecuteReader();
                bool hasRows = dataReader.HasRows;
                dataReader.Close();
                return !hasRows;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]IsSafeString err, {1}", NetManager.GetNowTime(), ex.Message);
                return false;
            }
        }

        //注册
        public static RegisterResult Register(string id, string pw)
        {
            CheckAndReconnect();

            if (!IsSafeString(id))
            {
                Console.WriteLine("[{0}][数据库]Register fail, id not safe", NetManager.GetNowTime());
                return RegisterResult.NotSafe;
            }

            if (!IsSafeString(pw))
            {
                Console.WriteLine("[{0}][数据库]Register fail, pw not safe", NetManager.GetNowTime());
                return RegisterResult.NotSafe;
            }

            if (!IsAccountExist(id))
            {
                Console.WriteLine("[{0}][数据库]Register fail, id exist", NetManager.GetNowTime());
                return RegisterResult.ExistId;
            }

            //写入数据库User表
            string sql = string.Format("insert into account set id ='{0}' ,pw ='{1}';", id, pw);

            try
            {
                MySqlCommand cmd = new MySqlCommand(sql, Mysql);
                cmd.ExecuteNonQuery();
                return RegisterResult.Successful;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]Register fail, {1}", NetManager.GetNowTime(), ex.Message);
                return RegisterResult.Other;
            }
        }

        //创建角色
        public static RegisterResult CreateNewPlayer(string id)
        {
            CheckAndReconnect();

            if (!DbManager.IsSafeString(id))
            {
                Console.WriteLine("[{0}][数据库]CreateNewPlayer fail, id not safe", NetManager.GetNowTime());
                return RegisterResult.NotSafe;
            }

            //序列化
            PlayerData playerData = new PlayerData();
            string data = Js.Serialize(playerData);
            //写入数据库
            string sql = string.Format("insert into player set id ='{0}' ,data ='{1}';", id, data);
            try
            {
                MySqlCommand cmd = new MySqlCommand(sql, Mysql);
                cmd.ExecuteNonQuery();
                return RegisterResult.Successful;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]CreateNewPlayer err, {1}", NetManager.GetNowTime(), ex.Message);
                return RegisterResult.Other;
            }
        }

        //检测用户名密码
        public static LoginResult Login(string id, string pw)
        {
            CheckAndReconnect();

            if (!IsSafeString(id))
            {
                Console.WriteLine("[{0}][数据库]CheckPassword fail, id not safe", NetManager.GetNowTime());
                return LoginResult.NotSafe;
            }

            if (!IsSafeString(pw))
            {
                Console.WriteLine("[{0}][数据库]CheckPassword fail, pw not safe", NetManager.GetNowTime());
                return LoginResult.NotSafe;
            }

            //查询
            string sql = string.Format("select * from account where id='{0}' and pw='{1}';", id, pw);

            try
            {
                MySqlCommand cmd = new MySqlCommand(sql, Mysql);
                MySqlDataReader dataReader = cmd.ExecuteReader();
                bool hasRows = dataReader.HasRows; //HasRows为True代表存在这一条数据 及Id密码对应
                dataReader.Close();
                return hasRows ? LoginResult.Successful : LoginResult.WrongIdOrPw;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]CheckPassword err, {1}", NetManager.GetNowTime(), ex.Message);
                return LoginResult.Other;
            }
        }

        //获取玩家数据
        public static PlayerData GetPlayerData(string id)
        {
            CheckAndReconnect();

            if (!IsSafeString(id))
            {
                Console.WriteLine("[{0}][数据库]GetPlayerData fail, id not safe", NetManager.GetNowTime());
                return null;
            }

            string sql = string.Format("select * from player where id ='{0}';", id);

            try
            {
                //查询
                MySqlCommand cmd = new MySqlCommand(sql, Mysql);
                MySqlDataReader dataReader = cmd.ExecuteReader();
                if (!dataReader.HasRows)
                {
                    dataReader.Close();
                    return null;
                }

                //读取
                dataReader.Read();
                string data = dataReader.GetString("data");
                //反序列化
                PlayerData playerData = Js.Deserialize<PlayerData>(data);
                dataReader.Close();
                return playerData;
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]GetPlayerData fail, {1}", NetManager.GetNowTime(), ex.Message);
                return null;
            }
        }

        //保存角色
        public static void UpdatePlayerData(string id, PlayerData playerData)
        {
            CheckAndReconnect();

            string data = Js.Serialize(playerData);

            string sql = string.Format("update player set data='{0}' where id ='{1}';", data, id);

            try
            {
                MySqlCommand cmd = new MySqlCommand(sql, Mysql);
                cmd.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                Console.WriteLine("[{0}][数据库]UpdatePlayerData err, {1}", NetManager.GetNowTime(), ex.Message);
            }
        }
    }
}